<?php

namespace App\Utils;

use Illuminate\Database\Eloquent\Model;

trait ModelOperatorTrait{
	abstract protected function model():Model;

	private function hasModel($model = null){
		if($model != null){
			$model = $model;
		}
		else{
			$model = $this->model();
		}

		return $model;
	}

	public function findModel($id,$with = [],Model $model = null){
		$model = $this->hasModel($model);

		return $model->with($with)->find($id);
	}

	public function queryModel(array $conditions,array $with = [],Model $model = null){

		$model = $this->hasModel($model);

		$fillable = $model->getFillable();

		if(is_array($model->getKeyName())){
			foreach ($model->getKeyName() as $primaryKey) {
				array_push($fillable,$primaryKey);
			}
		}
		else{
			array_push($fillable,$model->getKeyName());
		}

		$query = $model->query()->with($with);

		if(count($conditions) > 0){
			if(is_array($fillable) && !is_null($fillable) && count($fillable) > 0){
				$conditions = array_only($conditions, $fillable);
			}

			foreach ($conditions as $key => $value) {
				if(is_array($value)){
					$query->whereIn($key,$value);
				}
				else{
					$query->where($key, $value);
				}
			}
		}

		return $query;
	}

	public function firstModel(array $conditions,array $with = [],Model $model = null){
		$query = $this->queryModel($conditions,$with,$model);

		return $query->first();
	}

	public function pageModel(array $conditions,array $with = [],Model $model = null,$orderBy = null){
		$query = $this->queryModel($conditions,$with,$model);
		
		if($orderBy != null){
			$query = $query->orderBy($orderBy,'DESC');
		}
		
		if(request()->has('page')){
			$pageSize = 10;
            if(request()->has('pageSize')){
                $pageSize = request()->pageSize;
            }
			return $query->paginate($pageSize);
		}
		else{
			return $query->get();
		}
	}

	public function updateModel($id,$data,Model $model = null){
		$model = $this->hasModel($model);

		$updateObj = $this->findModel($id);

		$updateObj = $updateObj->update($data);

		return $updateObj;
	}

	public function storeModel($data,Model $model = null){

		$model = $this->hasModel($model);

		$fillable = $model->getFillable();

		if(is_array($fillable) && !is_null($fillable) && count($fillable) > 0){
			$data = array_only($data, $fillable);
		}

		return $model->create($data);
	}

	public function deleteModel($id,Model $model = null){
		$model = $this->hasModel($model);

		$deleteObj = $this->findModel($id);

		$deleteObj->delete();
	}

	public function dropModel(array $conditions,Model $model = null){

		$model = $this->hasModel($model);
		
		$query = $this->queryModel($conditions,[],$model);

		$dropDatas = $query->get();

		foreach($dropDatas as $dropData){
			$dropData->delete();
		}
	}
}